package com.taxinfo.utils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.crypto.Cipher;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import javax.crypto.spec.IvParameterSpec;
import java.security.Key;
import java.text.DecimalFormat;
import java.util.Base64;

/**
 * @author wanghy
 * DES 加密解密
 */
public class DesUtils {

    private static final Logger logger = LoggerFactory.getLogger(DesUtils.class);
    /**
     * 偏移变量，固定占8位字节
     */
    private final static String IV_PARAMETER = "12345678";
    /**
     * 密钥算法
     */
    private static final String ALGORITHM = "DES";
    /**
     * 加密/解密算法-工作模式-填充模式
     */
    private static final String CIPHER_ALGORITHM = "DES/CBC/PKCS5Padding";
    /**
     * 默认编码
     */
    private static final String CHARSET = "utf-8";


    private static Key generateKey(String password) throws Exception {
        DESKeySpec dks = new DESKeySpec(password.getBytes(CHARSET));
        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(ALGORITHM);
        return keyFactory.generateSecret(dks);
    }

    private static String formatKey(String key){
        if(key.length() < 8){
            DecimalFormat g1=new DecimalFormat("00000000");
            String startZeroStr = key;
            try {
                startZeroStr = g1.format(Integer.valueOf(key));
            }catch (Exception e){
                logger.error(key + "用户名非纯数字！");
                e.printStackTrace();
                startZeroStr = stringToFormat(key);
            }
            return startZeroStr;
        }

        return key;
    }

    private static String stringToFormat(String key){
        if (key != null && key.length() == 7){
            return "0"+key;
        }else if (key != null && key.length() == 6){
            return "00" + key;
        }else if (key != null && key.length() == 5){
            return "000" + key;
        }else if (key != null && key.length() == 4){
            return "0000" + key;
        }else if (key != null && key.length() == 3){
            return "00000" + key;
        }else if (key != null && key.length() == 2){
            return "000000" + key;
        }else if (key != null && key.length() == 1){
            return "0000000" + key;
        }else if (key != null && key.length() <= 0 || key == null){
            return "00000000";
        }else {
            return key;
        }
    }

    public static String encrypt(String data,String key,boolean encrypt) {
        if(!encrypt){
            return data;
        }
        key = formatKey(key);
        if (data == null)
            return null;
        try {
            Key secretKey = generateKey(key);
            Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
            IvParameterSpec iv = new IvParameterSpec(IV_PARAMETER.getBytes(CHARSET));
            cipher.init(Cipher.ENCRYPT_MODE, secretKey, iv);
            byte[] bytes = cipher.doFinal(data.getBytes(CHARSET));

            return new String(Base64.getEncoder().encode(bytes));
        } catch (Exception e) {
            e.printStackTrace();
            return data;
        }
    }

    public static String decrypt(String data,String key,boolean decrypt ) {
        if(!decrypt){
            return data;
        }
        key = formatKey(key);
        if (data == null){
            return null;
        }

        try {
            Key secretKey = generateKey(key);
            Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
            IvParameterSpec iv = new IvParameterSpec(IV_PARAMETER.getBytes(CHARSET));
            cipher.init(Cipher.DECRYPT_MODE, secretKey, iv);
            return new String(cipher.doFinal(Base64.getDecoder().decode(data.getBytes(CHARSET))), CHARSET);
        } catch (Exception e) {
            logger.error("DES解密失败【{}】",key);
            e.printStackTrace();
            return "DES解密失败【"+key+"】";
        }
    }


    public static void main(String[] args){
        try {
            String password = "123456";
            String username = "3456";

            String encryptPassword = encrypt(username,password,true);

            System.out.println(encryptPassword);

            System.out.println(decrypt(username,encryptPassword,true));
        }catch (Exception ex){
            ex.printStackTrace();
        }

    }
}
